package cc.eddic.practice.concurrency.QiNiuImpl;

import cc.eddic.practice.concurrency.LogItem;
import cc.eddic.practice.concurrency.QiNiuLogItem;

import cc.eddic.practice.concurrency.QiNiuLogParser;
import cc.eddic.practice.concurrency.impl.LogItemParserScwImpl;
import cc.eddic.practice.concurrency.impl.LogParserWithFutureScwImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.Model;

import java.io.*;
import java.util.zip.GZIPInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.*;

@Slf4j
public class QiNiuLogParserScwImpl implements QiNiuLogParser {
    private static final int LOG_FILE_COUNT = 2307;

    @Override
    public Map<String, List<QiNiuLogItem>> parse(String folderName) {
        Map<String, List<QiNiuLogItem>> resultMap = new ConcurrentHashMap<>();
        ExecutorService executorService = Executors.newFixedThreadPool(256);
        CountDownLatch latch = new CountDownLatch(LOG_FILE_COUNT);
        traverseFolder(new File(folderName), resultMap, executorService, latch);
        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            executorService.shutdown();
        }
        return resultMap;
    }

    private void parseLogFile(String path, Map<String, List<QiNiuLogItem>> resultMap, CountDownLatch latch) throws IOException {
        List<QiNiuLogItem> logItems = new ArrayList<>();
        LogItemParserQiNiuScwImpl logItemParser = new LogItemParserQiNiuScwImpl();
        FileInputStream fis = new FileInputStream(path);
        GZIPInputStream gzis = new GZIPInputStream(fis);
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(gzis))) {
            String line;
            while ((line = reader.readLine()) != null) {
                Optional<QiNiuLogItem> parsedLogItem = logItemParser.parse(line);
                parsedLogItem.ifPresent(logItems::add);
            }
            log.info("{}", resultMap.size());
            resultMap.put(path, logItems);
            log.info("{}", resultMap.size());
        } finally {
            latch.countDown();
        }
    }

    private void traverseFolder(File fileFolder, final Map<String, List<QiNiuLogItem>> resultMap, ExecutorService executorService, CountDownLatch latch) {
        File[] files = fileFolder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    traverseFolder(file, resultMap, executorService, latch);
                } else if (file.getName().endsWith(".gz")) {
                    executorService.submit(() -> {
                        try {
                            parseLogFile(file.getAbsolutePath(), resultMap, latch);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });

                }
            }
        }


    }
}

//                }else if
//                (file.getName().endsWith(".cc_2023-04-01-01_part-00000")) {
//                    executorService.submit(() -> {
//                        try {
//                            parseLogFile(file.getAbsolutePath(),resultMap,latch);
//                        } catch (IOException e) {
//                            throw new RuntimeException(e);
//                        }
//                    });
//                }